#include <iostream>
#include <string>
using namespace std;

/* 饮料 */
class Beverage 
{
public:
    Beverage(string str = "Unknow Beverage")
        :description(str){}

    virtual string getDescription()
    {
        return description;
    }

    virtual double cost(){return 0;}

private:
    string description;
};

/* 调料 */
class CondimentDecorator : public Beverage     
{
public:
    string getDescription(){return "";}
};

/*  浓咖啡 */
class Espresso : public Beverage
{
public:

    Espresso():Beverage("Espresso"){}

    double cost()
    {
        return 1.99;
    }
};

/* HouseBlend Coffee */
class HouseBlend : public Beverage
{
public:
    HouseBlend():Beverage("HouseBlend Coffee"){}

    double cost()
    {
        return 0.89;
    }
};

/* 摩卡*/
class Mocha : public CondimentDecorator
{
public:
    Mocha(Beverage* beve)
    {
        beverage = beve;
    }

    string getDescription()
    {
        return beverage->getDescription()+", Mocha";
    }

    double cost()
    {
        return 0.20 + beverage->cost();
    }
private:
    Beverage* beverage;
};

class Whip : public CondimentDecorator
{
public:
    Whip(Beverage* beve)
    {
        beverage = beve;
    }

    string getDescription()
    {
        return beverage->getDescription()+", Whip";
    }

    double cost()
    {
        return 0.15 + beverage->cost();
    }
private:
    Beverage* beverage;
};

int main()
{
    Beverage* pBeverage = new Espresso();
    cout << pBeverage->getDescription() << " $" << pBeverage->cost() << endl;

    Beverage* pBeverage2 = new Espresso();
    pBeverage2 = new Mocha(pBeverage2);
    pBeverage2 = new Mocha(pBeverage2);
    cout << pBeverage2->getDescription() << " $" << pBeverage2->cost() << endl;

    pBeverage2 = new Whip(pBeverage2);
    cout << pBeverage2->getDescription() << " $" << pBeverage2->cost() << endl;

    return 0;
}
